﻿using System.Collections.Generic;
using UnityEngine;
using Yoozoo.Libs;
using Random = UnityEngine.Random;
using System;
using System.Linq;
using com.yoozoo.gta.Extension;
using com.youzu.got.protocol;
using Gameplay.RTS.ScriptConfig;
using LogSystem;
using UnityEngine.Profiling;
using Yoozoo.Gameplay.RTS.Proto;
using WorldMap;
using XLua;
using Yoozoo.Framework.Managers;

namespace Yoozoo.Gameplay.RTS
{
    public class MarchSquare : IClass
    {
        //private readonly Dictionary<int, int> _soldierIdCountInitDic = new Dictionary<int, int>(); //方阵创建时的士兵数目
        //private readonly List<int> _soldierLodIdList = new List<int>();
        private bool isInit = false;
        private int _beforeLodLevel = -1;
        private GameObject _marchSmokeEff;
        private Vector3 _originForward = new Vector3(0, 0, 1);
        private bool _playSmoke;
        private readonly Dictionary<int, int> _soldierIdCountCurrentDic = new Dictionary<int, int>(); //士兵id，对应当前的模型数目
        //private List<int> _soldierIdList = new List<int>();
        private GameObject _troopSelfTroopEffect;
        private GameObject _troopMarchSkin;
        private int _marchSkinResId;
        private bool _startDispose = false;
        private bool _startHide = false;
        private float _startDisposeTime = 0;
        private float _startHideTime = 0;

        private float _targetAlpha;
        public int CurrentRangeType = 0;
        public bool IsPincer;
        // 本来是设计来存储行军数据
        public MarchInfo MarchInfo;
        //Lua 持有的一个对象，是为了对Lua提供操作接口
        public MarchEntity MarchEntity;
        
        
        public float RadFromOriginForward;
        public EMarchStatus MarchClientMarchStatue => MarchInfo.ClientMarchStatue;
        public float speed => MarchInfo.Speed;
        public Vector3 EndPosition => MarchInfo.EndPosition;
        public Vector3 StartPosition => MarchInfo.StartPosition;
        public Vector3 PreForward => MarchInfo.BeforeForward;
        public Vector3 Forward => MarchInfo.CurrentForward;
        private float attackEffectInterval = 0.6f;
        private float attackCurrentTime;
        private float attackCurrentTime2;
        private bool firstPlayAttack = true;
        private TSoldiersThrowable attackData;


        //方阵数据所在的索引
        public int squareDataIndex = -1;
        
        //方阵状态枚举
        private const int Enum_MarchState_Idle = 0;
        private const int Enum_MarchState_Move = 1;
        private const int Enum_MarchState_Attack = 2;
        private const int Enum_MarchState_DIE = 3;
        private const int Enum_MarchState_PlyDIEIdle =4;
        private const int Enum_MarchState_CrossingGate = 6;
        private const int Enum_MarchState_ClientAttack = 7;
        private const int Enum_MarchState_ExternalMovement = 8;

        private int modelTotalNum;
        public bool fixedSoldierID;
        private bool modelTotalNumChange;
        public List<SoldierLocation> formationPos;
        public List<BattleFormationCfg> formationCfgs;
        //private TroopsSoldier[] serversoldierList;

        private SquareModel squareModel;
        private UnionTrialBossViewCheck bossView;
        private bool visible;
        private bool initedChildren;
        private bool initedModel;
        //该部队的阵型id
        private int formationType;
        private float _attackRange = 0.4f;
        private float alpha = 0;

        private float fadeStartTime = -1;
        private float fadeStartAlpha;
        private float fadeTime = 0.5f;

        private float delayFadeTime = -1;
        private float delayFadeDuration;
        private float delayFadeTargetAlpha = 0;

        private GameObject truckEffect;
        private GameObject truckEffectSub1;
        private GameObject truckEffectSub2;
        private bool hasTruckEffect = false;

        private bool isTruck;
        private bool isTruckAttack;

        private bool isTrain;
        private bool isTrainAttack;
        public int Team
        {
            get
            {
                if (MarchEntity != null)
                {
                    return MarchInfo.Team;
                }

                return 2;
            }
        }
        public void OnReset()
        {
            RemoveSelfTroopEffect();
            if (MarchEntity!=null && _marchSkinResId != 0)
            {
                RemoveTroopMarchSkin(_marchSkinResId);
            }
            ArmyManager.Instance.ResourceManager.RecoverResourceById(901,_marchSmokeEff);
            _playSmoke = false;
            _marchSmokeEff = null;
            MarchEntity = null;
            MarchInfo = null;
            isInit = false;
        }
        public void Dispose()
        {
            HideAttackSpeedEffect();
            HideTruckEffect();
            HideTrainEffect();
            _currentShowForward = Vector3.zero;
            modelTotalNum = 0;
            EndCrossingGate();
            SquareDataManager.Instance.RecoverSquareAsync(squareDataIndex);
            squareDataIndex = -1;
            ambulanceIndex = -1;
            isClientInBattle = false;
            cachedFormationType = -1;
            cachedSoldierCount = -1;
            cachedSquareStatus = 0;
            isEscape = false;
            isShowAmbulance = false;
            battleStartTime = -1;
            isBattleTransforming = false;
            isFakeMoveForward = false;
            isFakeMoveForwardEnd = false;
            OnReset();
            if (squareModel!=null)
            {
                DisposeModel();
            }
            if (bossView!=null)
            {
                bossView = null;
            }

            fadeStartTime = -1;
            delayFadeTime = -1;
            DestroySmuggleEffect();
            if (MarchEntity!=null && _marchSkinResId != 0)
            {
                RemoveTroopMarchSkin(_marchSkinResId);
            }
            isTruck = false;
            isTruckAttack = false;

            isTrain = false;
            isTrainAttack = false;
        }

        private void DisposeModel()
        {
            squareModel.Dispose();
            squareModel = null;
        }

        public void BeforeDispose()
        {
            HideAttackSpeedEffect();
            HideTruckEffect();
            HideTrainEffect();
            if (!_startDispose)
            {
                _startDispose = true;
            }
        }

        public void BeforeHide()
        {
            HideAttackSpeedEffect();
            CheckShowTroopMarchSkin();
            if (!_startHide && _targetAlpha != 0)
            {
                _startHide = true;
            }
            _targetAlpha = 0;
        }

        private void BeforeShow()
        {
            CheckShowTroopMarchSkin();
            if (!_startHide)
            {
                _startHide = true;
            }
            _targetAlpha = 1;
        }

        public void ShowSquare()
        {
            _targetAlpha = 1;
            _startHideTime = 0;
            SetChildrenPosition(true);
            SetChildrenAlpha(1);
            CheckShowTroopMarchSkin();
        }
        private void RecoverModelUnit()
        {
            
        }

        public void Initialize(MarchEntity marchEntity)
        {
            if (isInit)
            {
                Debug.LogError($"MarchSquare is Inited... {marchEntity.Tid}");
            }

            isTruck = marchEntity.TargetCoordinateType == TargetCoordinateType.INTERCITY_TRADE_TRUCK_45;
            isTrain = marchEntity.TargetCoordinateType == TargetCoordinateType.TRAIN_51;
            isTruckAttack = marchEntity.isTruckAttackerMarch();
            isTrainAttack = marchEntity.isTrainAttackerMarch();
            cachedFormationType = -1;
            cachedSoldierCount = -1;
            cachedSquareStatus = 0;
            isEscape = false;
            isInit = true;
            initedChildren = false;
            initedModel = false;
            _startDispose = false;
            _beforeLodLevel = -1;
            MarchEntity = marchEntity;
            MarchInfo = marchEntity.MarchInfo;
            _soldierIdCountCurrentDic.Clear();
            OnGlobalScaleChanged(RTSLuaCallCSharpManager.marchLodLevel, RTSLuaCallCSharpManager.lodScale);
        
            SetDefaultCampColor();
#if UNITY_EDITOR
            //RTSTest.AddBattleSquare(this);
#endif
            //CheckSoldierDeadOrReborn(MarchInfo.SoldierCount);
            IsPincer = false;
            int attackDataIndex = 2000 + MarchInfo.SoldierType;//不同兵种用不同的攻击特效 混兵使用2005
            attackData = ArmyManager.Instance.ResourceManager.JsonManager.GetThrowableConfigBySoldierType(attackDataIndex);
            if (attackData == null)
            {
                attackData = ArmyManager.Instance.ResourceManager.JsonManager.GetThrowableConfigBySoldierType(2005);
            }
        }
        
        private void InitMarchSquareData()
        {
            squareDataIndex = SquareDataManager.Instance.GetNewSquare();
            //Profiler.BeginSample("MarchManager.InitMarchSquareData.InitSquare");
            var team = GetSquareTeam(MarchInfo.Team);
            SquareDataManager.Instance.InitSquare(squareDataIndex,MarchInfo.Uid,MarchEntity.TargetCoordinateType,SoldierLodIdList,MarchEntity.ClientMarchType == EClientMarchType.Monster,MarchInfo.SoldierCount == 0, team, this.formationPos);
            //Profiler.EndSample();
            //Profiler.BeginSample("MarchManager.InitMarchSquareData.SetTeam");
            //SquareDataManager.Instance.SetTeam(squareDataIndex, MarchInfo.Team,true);
            //Profiler.EndSample();
            //Profiler.BeginSample("MarchManager.InitMarchSquareData.SetData");
            SquareDataManager.Instance.SetAlpha(squareDataIndex,1);
            SetMarchDataToSquareData();
            CheckNeedApplyCachedData();
            SetChildrenForward(MarchEntity.Forward,true);
            //Profiler.EndSample();
        }

        /// <summary>
        /// 把行军信息数据赋值
        /// </summary>
        public void SetMarchDataToSquareData()
        {
            if (isFakeMoveForward)
            {
                return;
            }

            var duration = MarchInfo.CurrentSegmentDuration;
            if (duration > 0)
            {
                SquareDataManager.Instance.SetStartPosition(squareDataIndex,MarchInfo.SegmentStartPosition);
                SquareDataManager.Instance.SetEndPosition(squareDataIndex,MarchInfo.EndPosition);
                SquareDataManager.Instance.SetSegmentDuration(squareDataIndex, MarchInfo.CurrentSegmentDuration);
            }
            else
            {
                SquareDataManager.Instance.SetStartPosition(squareDataIndex,MarchInfo.Position);
                SquareDataManager.Instance.SetEndPosition(squareDataIndex,MarchInfo.Position);
                SquareDataManager.Instance.SetSegmentDuration(squareDataIndex, 0);
            }
            
            SquareDataManager.Instance.SetSpeed(squareDataIndex,MarchInfo.Speed);
            
            
            CheckNeedRefreshSegmentStartTime();
            SetPosition(MarchEntity.Position, MarchEntity.MarchInfo.IsForceMoveChild);
            SetForward(MarchEntity.Forward);
            
            //如果不是过桥状态，检查一下当前是否是过桥阵型
            if (MarchInfo.ClientMarchStatue != EMarchStatus.CrossingGate && crossingGateFormationIndex >= 0)
            {
                EndCrossingGate();
            }
        }

        public void StartCrossingGate(bool needShowTransition = true)
        {
            if (crossingGateFormationIndex == -1)
            {
                if (needShowTransition)
                {
                    BeforeHide();
                }
                else
                {
                    _targetAlpha = 0;
                    SetChildrenAlpha(0);
                }
               
                var formationId = MarchHelper.CrossingGateFormationId;
                if (MarchEntity.RtsServerInfo.isAssemblyLeader)
                {
                    formationId = MarchHelper.CrossingGateAssemblyFormationId;
                }
                crossingGateFormationIndex =
                    SquareDataManager.Instance.CreateCrossingGateFormation(squareDataIndex, formationId, Forward);
            }
        }

        public void EndCrossingGate()
        {
            if (crossingGateFormationIndex != -1)
            {
                BeforeShow();
                SquareDataManager.Instance.RemoveCrossingGateFormation(crossingGateFormationIndex);
                crossingGateFormationIndex = -1;
            }
        }

        private int crossingGateFormationIndex = -1;
        
        private float segmentStartTime;

        private void CheckNeedRefreshSegmentStartTime()
        {
            if (MarchInfo.ClientMarchStatue == EMarchStatus.CrossingGate)
            {
                SquareDataManager.Instance.SetSegmentStartTime(squareDataIndex,MarchInfo.CrossingGateStartClientTime);
            }
            else if (MarchInfo.CurrentSegmentDuration > 0 || MarchInfo.Segment.NeedSyncToMarchData)
            {
                var segmentStartTime = MarchInfo.Segment.startTime;
                //   Debug.Log(LogModule.RTS,$" framecount:{Time.frameCount} {MarchInfo.Uid}-0 更新 线段开始时间  this.segmentStartTime = {this.segmentStartTime} segmentStartTime = {segmentStartTime} ");
                if (Math.Abs(segmentStartTime - this.segmentStartTime) > 0.001f)
                {
                    //Debug.Log(LogModule.RTS,$" framecount:{Time.frameCount} {MarchInfo.Uid}-0 更新 线段开始时间  this.segmentStartTime = {this.segmentStartTime} segmentStartTime = {segmentStartTime} ");
                    SquareDataManager.Instance.SetSegmentStartTime(squareDataIndex,segmentStartTime);
                    this.segmentStartTime = segmentStartTime;
                }
           
                var segment = MarchInfo.Segment;
                segment.NeedSyncToMarchData = false;
            }
        }

        public void SetTeam(int team)
        {
            team = GetSquareTeam(team);
            SquareDataManager.Instance.SetTeam(squareDataIndex, team,false,formationPos);
        }

        private int cachedSquareStatus;
        private void SetSquareStatus(int status)
        {
            if (isTruck || isTruckAttack || isTrainAttack)
            {
                status = Enum_MarchState_ExternalMovement;
            }
            cachedSquareStatus = status;
            SquareDataManager.Instance.SetMarchStatus(squareDataIndex,status);
            //UnityEngine.Debug.LogError(MarchEntity.Tid+ " SetMarchStatus" + cachedSquareStatus);
            squareModel?.SetSquareStatus(status);
        }

        private int cachedFormationType = -1;
        private int cachedSoldierCount = -1;
        public void SetFormationType(int formationType, int soldierCount)
        {
            cachedFormationType = formationType;
            cachedSoldierCount = soldierCount;
            SquareDataManager.Instance.SetFormationId(squareDataIndex,formationType,soldierCount);
        }

        private void CheckNeedApplyCachedData()
        {
            SquareDataManager.Instance.SetClientInBattle(squareDataIndex,isClientInBattle);
            SquareDataManager.Instance.SetMarchStatus(squareDataIndex,cachedSquareStatus);
            //UnityEngine.Debug.LogError(MarchEntity.Tid+ " SetMarchStatus" + cachedSquareStatus);
            if (cachedFormationType >= 0)
            {
                SquareDataManager.Instance.SetFormationId(squareDataIndex,cachedFormationType,cachedSoldierCount);
                cachedFormationType = -1;
            }
        }

        private void SetDefaultCampColor()
        {
            //SetTeamColor(MarchEntity.MarchInfo.Team);
        }

        public void Update(float realTime,int lodLevel)
        {
            this.realTime = realTime;
            
            MarchEntity.isServerPosChange = false;

            if (_troopMarchSkin != null)
            {
                _troopMarchSkin.transform.forward = MarchEntity.Forward ;
                _troopMarchSkin.transform.localRotation = Quaternion.Euler(_troopMarchSkin.transform.localEulerAngles.x, _troopMarchSkin.transform.localEulerAngles.y - 100, _troopMarchSkin.transform.localEulerAngles.z);
            }
            
            if (squareModel!=null)
            {
                squareModel.OnUpdate();
            }
            if (MarchClientMarchStatue == EMarchStatus.Battle)
            {
                /*if (attackCurrentTime == 0)
                {
                    firstPlayAttack = true;
                }
                if (attackCurrentTime > attackEffectInterval || firstPlayAttack)
                {
                    InitAttackEffectIntervalParam();
                    if (!firstPlayAttack)
                    {
                        attackCurrentTime = 0;
                    }
                    else
                    {
                        firstPlayAttack = false;
                    }
                }
                else
                {
                    UpdateAttackEffect();
                }
                attackCurrentTime += deltaTime;*/
            }
            else
            {
                attackCurrentTime = 0;
                firstPlayAttack = false;
            }

            if (_startHide)
            {
                _startHide = false;
                _startHideTime = realTime;
            }

            if (_startHideTime != 0)
            {
                float deleteTime = 0.5f;
                if (realTime - _startHideTime < 1)
                {
                    var percent = (realTime - _startHideTime) / deleteTime;
                    float alpha = Mathf.Clamp01(1 - percent);
                    if (_targetAlpha == 1)
                    {
                        alpha = 1 - alpha;
                    }
                    SetChildrenAlpha(alpha);
                }
                else
                {
                    SetChildrenAlpha(_targetAlpha);
                    _startHideTime = 0;
                    isFakeMoveForward = false;
                }
            }

            if (fadeStartTime >= 0)
            {
                var percent = (Time.time - fadeStartTime) / fadeTime;
                if (percent >= 0)
                {
                    if (percent >= 1)
                    {
                        percent = 1;
                        fadeStartTime = -1;
                    }
                    var a = Mathf.Lerp(fadeStartAlpha, _targetAlpha, percent);
                    SetChildrenAlpha(a);
                }
            }
            else if (delayFadeTime > 0)
            {
                if (delayFadeTime > Time.time)
                {
                    if (delayFadeTargetAlpha == 0)
                    {
                        FadeOut(delayFadeDuration);
                    }
                    else
                    {
                        FadeIn(delayFadeDuration);
                    }
                    delayFadeTime = -1;
                }
            }

            if (isFakeMoveForward)
            {
                if (!isFakeMoveForwardEnd && TimeUtils.GetClientTickTime() >= fakeMoveForwardEndTime)
                {
                    StopFakeMoveForward();
                    isFakeMoveForwardEnd = true;
                }
            }

            if (isBattleTransforming && battleStartTime >= 0)
            {
                if (realTime - battleStartTime > 0f)
                {
                    isBattleTransforming = false;
                    battleStartTime = -1;
                    var target = MarchEntity.GetBattleTarget();
                    if (!CheckDistanceWithTargetOutRange(target))
                    {
                        ShowAttackSpeedEffect();
                    }
                }
            }
            if (attackSpeedEffect != null)
            {
                var target = MarchEntity.GetBattleTarget();
                var isTruckFighting =
                    MarchEntity.isTruckAttackerMarch() || (target != null && target.isTruckAttackerMarch());
                //if (MarchInfo.SoldierCount > 0 && target != null && (target.MarchInfo.ClientMarchStatue != EMarchStatus.Escape && target.MarchInfo.SoldierCount > 0))
                if (isTruckFighting || MarchInfo.SoldierCount > 0 && target != null && target.MarchInfo.ClientMarchStatue != EMarchStatus.Escape)
                {
                    var position = target.Position;//(target.Position + Position) / 2;
                    var forward = target.Position - MarchEntity.Position;
                    if (forward == Vector3.zero)
                    {
                        forward = Vector3.forward;
                    }
                    attackSpeedEffect.transform.position = position;
                    attackSpeedEffect.transform.forward = forward;
                }
                else if(MarchInfo.ClientMarchStatue == EMarchStatus.Collect){
                    var position = MarchEntity.RtsServerInfo.targetPosition;
                    var forward = MarchEntity.RtsServerInfo.targetPosition - MarchEntity.Position;
                    if (forward == Vector3.zero)
                    {
                        forward = Vector3.forward;
                    }
                    if (position != default)
                    {
                        attackSpeedEffect.transform.position = position;
                        attackSpeedEffect.transform.forward = forward;
                    }
                }
                else
                {
                    HideAttackSpeedEffect();
                }

                if (currentDistanceTime > checkDistanceTime)
                {
                    if (CheckDistanceWithTargetOutRange(target))
                    {
                        HideAttackSpeedEffect();
                    }
                    currentDistanceTime = 0;
                }
                currentDistanceTime += Time.deltaTime;
            }

            if (isTruck || isTruckAttack || isTrainAttack)
            {
                //UpdateTruckCrush();
                SetPosition(MarchEntity.Position,true);
                SetForward(MarchEntity.Forward);
            }
        }

        private bool CheckDistanceWithTargetOutRange(MarchEntity target)
        {
            if (target == null)
            {
                return false;
            }
            else
            {
                if (target.isTruckAttackerMarch() || MarchEntity.isTruckAttackerMarch())
                {
                    return false;
                }
                if (Vector3.Distance(target.Position,MarchEntity.Position) > _attackRange * 1.5f)
                {
                    return true;
                }
            }
            return false;
        }
        private float checkDistanceTime = 0.5f;
        private float currentDistanceTime = 0;
        public void UpdateOnWaitDispose()
        {
            var currentTime = Time.time;
            if (_startDispose)
            {
                _startDispose = false;
                _startDisposeTime = currentTime;
            }

            float deleteTime = 0.5f;
            if (currentTime - _startDisposeTime < 1)
            {
                var percent = (currentTime - _startDisposeTime) / deleteTime;
                float alpha = Mathf.Clamp01(1 - percent);
                SetChildrenAlpha(alpha);
            }
            else
            {
                MarchEntity.IsWaitDelete = true;
                RecoverModelUnit();
            }
        }

        public void SetStartHide()
        {
            if (!_startHide)
            {
                _startHide = true;
                MarchEntity.IsWaitDelete = true;
            }
            _targetAlpha = 0;
        }
        public int GetSoldierLiveNum()
        {
            return 0;
            /*if (_soldiersList == null)
            {
                return 0;
            }

            int result = 0;
            foreach (var soldierUnit in _soldiersList)
            {
                if (!soldierUnit.IsDeadOver && !soldierUnit.IsDeadStart)
                {
                    result++;
                }
            }

            return result;*/
        }

        /// <summary>
        /// 部队中显示多少个模型
        /// </summary>
        /// <returns></returns>
        public int GetActiveModelCount()
        {
            return 0;
            /*if (_commanderList == null)
                return 0;

            int count = _commanderList.Count;

            if (_soldiersList == null)
                return count;

            foreach (var soldierUnit in _soldiersList)
            {
                if (soldierUnit.GetRenderVisible())
                    count++;
            }

            return count;*/
        }

        /// <summary>
        /// 部队中多少个模型因为性能预算被丢弃
        /// </summary>
        /// <returns></returns>
        public int GetDiscardModelCount()
        {
            return 0;
            /*if (_soldiersList == null)
                return 0;

            int count = 0;
            foreach (var soldierUnit in _soldiersList)
            {
                // 应该显示但是被丢弃的模型
                if (soldierUnit.Visible && soldierUnit.InCamera && soldierUnit.IsDiscard)
                    count++;
            }

            return count;*/
        }

        public void RoundFight(List<int> soldierPair)
        {
            /*if (soldierPair != null && soldierPair.Count > 0)
            {
                CheckSoldierDeadOrReborn(MarchInfo.SoldierCount,soldierPair);
            }*/
            
        }
        
        /// <summary>
        /// 
        /// </summary>
        /// <param name="squareSoldierCount"></param>
        /// <param name="isInit"> 是否初始化的时候调用的</param>
        public void CheckSoldierDeadOrReborn(int soldierNum,List<int>  soldierPair=null)
        {
            //this.cacheChildStateAction = ChildStateAction.Dead; 
            if (MarchEntity.fixedSoldierID)  //固定阵型，不减兵
            {
                return; 
            }
            RefreshCurrentSoldierCountDic(soldierNum,soldierPair);
           // foreach (var item in _soldierIdCountCurrentDic)
            // {
            //     Debug.Log($"{MarchInfo.Uid} CheckSoldierDeadOrReborn ..... key = {item.Key}  num = {item.Value}");
            // }
           
            //上一次的模型数目
            Dictionary<int, int> lastModelDic = new Dictionary<int, int>();

            //先检查死亡
            bool teamOver = true;
             /*for (int i = 0; i < _soldiersList.Count; i++)
            {
                if (_soldiersList[i].IsDeadStart)
                {
                    continue;
                }

                int soldierId = _soldiersList[i].ModelType;
                if (!lastModelDic.ContainsKey(soldierId))
                {
                    lastModelDic[soldierId] = 0;
                }

                lastModelDic[soldierId]++;
                int currentSoldierNum = 0;
                _soldierIdCountCurrentDic.TryGetValue(soldierId, out currentSoldierNum);
                if (lastModelDic[soldierId] > currentSoldierNum) //多出来的士兵，死
                {
                    _soldiersList[i].SetStateAction(ChildStateAction.Dead,this.realTime);
                        lastModelDic[soldierId]--;
                }

                //小兵数量大于0 则不标记队伍击溃
                if (lastModelDic[soldierId] > 0)
                {
                    teamOver = false;
                }
            }*/

            if (teamOver)
            {
                PlayRunAwayEffect();
            }
        }

        public void PlayRunAwayEffect()
        {
        }

        public void SetSoldierNum(int soldierCount)
        {
            SquareDataManager.Instance.SetSoldierNum(squareDataIndex,MarchInfo.InitSoldierCount,soldierCount);
            CheckNeedResetChildrenNum(soldierCount);
        }

        public void SetForward(Vector3 forward, bool setChild = false)
        {
            if (forward == Vector3.zero || forward == _currentShowForward)
            {
                return;
            }
            
            _currentShowForward = forward;
            
            if (MarchEntity.forwardObjList != null)
            {
                var forwardObjList = MarchEntity.forwardObjList;
                int len = forwardObjList.Count;
                // 设置C#相关的forward
                for (int i = 0; i < len; i++)
                {
                    forwardObjList[i].forward = MarchInfo.CurrentForward;
                }
            }
            SetChildrenForward(forward,setChild);
            if (squareModel!=null)
            {
                squareModel.SetForward(forward);
            }
        }

        public void SetServerPosChanged()
        {
            SquareDataManager.Instance.SetIsServerPosChange(squareDataIndex, true);
        }

        public void SetChildrenForward(Vector3 rotation,bool setChild = false)
        {
            SquareDataManager.Instance.SetForward(squareDataIndex,rotation,setChild,MarchEntity.ClientMarchType != EClientMarchType.Scout && MarchEntity.ClientMarchType != EClientMarchType.Rescue);
        }

        public void SetChildrenAlpha(float alpha)
        {
            this.alpha = alpha;
            SquareDataManager.Instance.SetAlpha(squareDataIndex,alpha);
            squareModel?.SetAlpha(alpha);
        }
        

        public void SetChildrenPosition(bool setChild = false)
        {
            if (isFakeMoveForward)
            {
                return;
            }
            SquareDataManager.Instance.SetPosition(squareDataIndex,MarchEntity.Position,setChild);
        }

        public void SetPosition(Vector3 position,bool forceMoveChildren)
        {
            if (isFakeMoveForward)
            {
                return;
            }
            SquareDataManager.Instance.SetPosition(squareDataIndex,position, forceMoveChildren);
            if (squareModel != null )
            {
                squareModel.SetPosition(position);
            }
        }

        private void CheckSelfTroopEffect(int lodLevel)
        {
            if (Team != 0)
            {
                return;
            }
            var isShow = lodLevel >= WorldEntry.MaxShowMarchLodLevel;
            if (isShow)
            {
                //2023.11.12 新修改，根据rok2的规则，进入矿，进入建筑的部队不显示扩散圈
                var marchStatus = MarchInfo.ClientMarchStatue;
                if (marchStatus == EMarchStatus.Collect || marchStatus == EMarchStatus.InBuilding ||
                    marchStatus == EMarchStatus.SIEGE_FIGHT)
                {
                    isShow = false;
                }
            }
            
            if (isShow)
            {
                ShowSelfTroopEffect();
            }
            else
            {
                RemoveSelfTroopEffect();
            }
        }

        private void ShowSelfTroopEffect()
        {
            if (_troopSelfTroopEffect == null)
            {
                //705 扩散的绿圈儿
                var troopEffect = ArmyManager.Instance.GetRtsResourceManager().GetResourceById(705);
                troopEffect.transform.SetParent(MarchEntity.Transform);
                troopEffect.transform.localPosition = new Vector3(0, 0, 0);
                troopEffect.transform.localScale = new Vector3(0.06f, 0.06f, 0.06f);
                _troopSelfTroopEffect = troopEffect;
            }
        }
        void CheckShowTroopMarchSkin()
        {
            var isShow = _beforeLodLevel < WorldEntry.MaxShowMarchLodLevel;
            if (MarchEntity.RtsServerInfo.Type != TargetCoordinateType.MARCH_3 )
            {
                isShow = false;
            }
            
            if (isShow && MarchEntity != null && MarchEntity.RtsServerInfo.marchSkinResId != 0  )
            {
                ShowTroopMarchSkin();
            }
            else
            {
                if (MarchEntity!=null && _marchSkinResId != 0)
                {
                    RemoveTroopMarchSkin(_marchSkinResId);
                }
            }
        }

        public void CheckNeedResetMarchSkin(int marchSkinResId)
        {
            CheckShowTroopMarchSkin();
        }
        
        private void ShowTroopMarchSkin()
        {
            var oldMarchSkinResId = _marchSkinResId;
            if (_marchSkinResId == 0)
            {
                _marchSkinResId = MarchEntity.RtsServerInfo.marchSkinResId;
            }
            if (_troopMarchSkin == null)
            {
                if (_marchSkinResId == 0 || !MarchEntity.Visible)  return;
                var troopMarchSkinEffect = ArmyManager.Instance.GetRtsResourceManager().GetResourceById(_marchSkinResId);
                if (troopMarchSkinEffect && troopMarchSkinEffect.Valid())
                {
                    troopMarchSkinEffect.transform.SetParent(MarchEntity.Transform);
                    troopMarchSkinEffect.transform.localPosition = new Vector3(0, -0.1f, 0);
                    troopMarchSkinEffect.transform.localScale = new Vector3(1f, 1f, 1f);
                    troopMarchSkinEffect.transform.forward = MarchEntity.Forward;
                    _troopMarchSkin = troopMarchSkinEffect;
                }
            }
            else
            {
                _troopMarchSkin.SetActive(MarchEntity.Visible);

                if (oldMarchSkinResId != MarchEntity.RtsServerInfo.marchSkinResId)
                {
                    RemoveTroopMarchSkin(oldMarchSkinResId);
                    ShowTroopMarchSkin();
                }
            }
        }
        
          private void RemoveTroopMarchSkin(int id)
          {
              _marchSkinResId = 0;
              if (_troopMarchSkin != null && id != 0)
              {
                  //获取_troopMarchSkin子节点下所有物体的particleSystem组件,并且全部调用Clear方法
                  Transform lod01 = _troopMarchSkin.transform.Find("lod01");
                  if (lod01 != null)
                  {
                        var particleSystems = lod01.GetComponentsInChildren<ParticleSystem>();
                        foreach (var particleSystem in particleSystems)
                        {
                            particleSystem.Clear();
                        }
                  }
                  ArmyManager.Instance.GetRtsResourceManager().RecoverResourceById(id, _troopMarchSkin);
                  _troopMarchSkin = null;
              }
          }
        
        
        public void OnGlobalScaleChanged(int lodLevel, float scale)
        {
            // if (_beforeLodLevel == BattleFormationHelper.VisibleLodLevel && lodLevel == 2) //这里的lod是行军的lod逻辑，跟沙盘的不太一样
            // {
            //     CheckSoldierDeadOrReborn(MarchInfo.SoldierCount);
            // }

            if (_beforeLodLevel != lodLevel && lodLevel >=  WorldEntry.MaxShowMarchLodLevel)
            {
                CheckSelfTroopEffect(lodLevel);
                SetArmyVisible(false);
            }

            if (lodLevel <  WorldEntry.MaxShowMarchLodLevel) //应该显示
            {
                CheckSelfTroopEffect(lodLevel);
                SetArmyVisible(true);
                ForceSetArmyPos();
            }
           

         
            //ChangeUnitsScale(scale);
            if (lodLevel != _beforeLodLevel)
            {
                if (lodLevel >= WorldEntry.MaxShowMarchLodLevel)
                {
                }
                ChangeLod(lodLevel);
            }

            _beforeLodLevel = lodLevel;
             CheckShowTroopMarchSkin();
            if (isTruck)
            {
                UpdateTruckEffect();
            }
            else if (isTrain)
            {
                UpdateTrainEffect();
            }
        }


        public void ClearChildrenCachePosition()
        {
            
        }

        public void ResetChildrenScale()
        {
            
        }

        public void ChangeLod(int level)
        {
            
        }


        public void Move()
        {
            IsPincer = false;
            if (MarchInfo.MarchType == MarchType.DIE_5)
            {
                SetSquareStatus(Enum_MarchState_DIE);
            }
            else if (MarchInfo.ClientMarchStatue == EMarchStatus.CrossingGate)
            {
                SetSquareStatus(Enum_MarchState_CrossingGate);
            }
            else
            {
                SetSquareStatus(Enum_MarchState_Move);
            }
            
            //AudioManager.PlaySound(RTSAudioEvent.SFX_RTS_TEAM_FOOTSTEP,MarchEntity.GetGameObject());
        }

        internal void SetIsInBattle(bool isInBattle)
        {
            squareModel?.SetIsInBattle(isInBattle);
        }

        public void Death()
        {
            UpdateSoldierNum(0, false);
            squareModel?.Death();
        }

        public void ResetScaleTest()
        {
            //if (_soldiersList != null)
            //{
            //    for (int i = 0; i < _soldiersList.Count; i++)
            //    {
            //        _soldiersList[i].SetScale(BattleUtils.GetSoldierLocalScaleByType(_soldiersList[i].ModelType));
            //        _soldiersList[i].OnScaleChanged(BattleUtils.GetSoldierLocalScaleByType(_soldiersList[i].ModelType));
            //    }
            //}
        }

        public void DoAttack(long targetTid = 0)
        {
            
        }

        public void DoIdle()
        {
            
        }
        

       
        //lod切换显示或隐藏
        public void SetArmyVisible(bool value)
        {
            this.visible = value;
            SquareDataManager.Instance.SetArmyVisible(squareDataIndex,value);
            if (squareModel!=null)
            {
                squareModel.SetModelVisible(value);
            }
            if (isShowAmbulance)
            {
                SquareDataManager.Instance.SetAmbulanceVisible(ambulanceIndex, value);
            }
            if (!value)
            {
                IsPincer = false;
                isClientInBattle = false;
                isBattleTransforming = false;
                HideAttackSpeedEffect();
            }

            var targetAlpha = 0;
            if (MarchInfo.NeedShowSquare())
            {
                targetAlpha = 1;
            }
            
            if (targetAlpha != _targetAlpha)
            {
                _targetAlpha = targetAlpha;
                SetChildrenAlpha(_targetAlpha);
                MarchInfo.marchSquareVisibleDirty = true;
            }

            if (smuggleEffect!=null)
            {
                smuggleEffect.SetActive(value);
            }
        }

        private void ForceSetArmyPos()
        {
           SetChildrenPosition(true);
        }
        

        public void SetTeamColor(int team)
        {
            Color color;
            if (team == 0)
            {
                //color = new Color(9 / 255f, 185 / 255f, 24 / 255f);
                ColorUtility.TryParseHtmlString("#2d5cb4", out color); //蓝色
            }
            else if (team == 1)
            {
                ColorUtility.TryParseHtmlString("#26bf33", out color); //绿色
            }
            else
            {
                ColorUtility.TryParseHtmlString("#981212", out color); //红色
            }

            // color = new Color(21 / 255f, 86 / 255f, 210 / 255f);蓝色
            /*foreach (var soldierUnit in _soldiersList)
            {
                soldierUnit.SetCampColor(color);
            }
            foreach (var commander in _commanderList)
            {
                commander.SetCampColor(color);
            }*/
        }


        public void ClearAttackState()
        {
            AttackToUnAttack();
            MarchEntity.EnemyTarget = null;
        }

        #region MarchEntity控制的阵型状态转换
        /// <summary>
        /// 攻击到非攻击状态
        /// </summary>
        public void AttackToUnAttack()
        {
            if (this.MarchEntity.CheckIsSelfMarch())
            {
                MarchManager.Instance.audioController?.PlaySquareBattleToNormalAudio();
            }
        }

        /// <summary>
        /// 其他状态进入攻击
        /// </summary>
        public void ReadyToAttack()
        {
            if (IsPincer || !visible)
            {
                return;
            }

            IsPincer = true;
            ReadyToBattle();
            if (this.MarchEntity.CheckIsSelfMarch())
            {
                MarchManager.Instance.audioController?.PlaySquareToBattleAudio();
            }
        }

        public void ReadyToCollect()
        {
            if (IsPincer || !visible)
            {
                return;
            }

            IsPincer = true;

            var forward = MarchInfo.GetTargetPosition() - MarchInfo.Position;
            MarchEntity.SetForward(forward);
            SetSquareStatus(Enum_MarchState_Attack);
        }

        /// <summary>
        /// 移动/战斗到驻扎
        /// </summary>
        public void MoveToStand()
        {
            IsPincer = false;
            var isMoveToStand = cachedSquareStatus == Enum_MarchState_Move;
            SetSquareStatus(Enum_MarchState_Idle);
            if (isMoveToStand && this.MarchEntity.CheckIsSelfMarch() && ArmyManager.Instance.CanPlayAudio(Team))
            {
                MarchManager.Instance.audioController?.PlaySquareToStationed();
            }
            else if (MarchEntity.TargetCoordinateType == TargetCoordinateType.TRAIN_51)
            {
                float aniPro = isMoveToStand ? 0 : 1; // 1代表驶入动画完全播放完
                TradeTrainModel train = squareModel as TradeTrainModel;
                train?.OnMoveInWonder(aniPro);
            }
        }

        public void UpdateTrainOutWonder()
        {
            // 列车播放进入奇观动画
            TradeTrainModel train = squareModel as TradeTrainModel;
            train?.OnMoveOutWonder(GetTrainOutAniPro());
        }

        private float GetTrainOutAniPro()
        {
            float aniPro = 1; // 1代表驶离动画完全播放完
            if (MarchEntity != null)
            {
                // 更新列车行驶出奇观的动画状态
                Coordinate curPos = MarchEntity.RtsServerInfo.coordinate;
                Coordinate[] path = MarchEntity.RtsServerInfo.pathList;
                if (path.Length >= 2)
                {
                    int idx = MarchEntity.RtsServerInfo.GetIdxInPathList(curPos);
                    Coordinate start = path[idx];
                    // 列车长度为Unity的4.5米
                    float trainLen = 4.5f;
                    float dis = Vector3.Distance(curPos.ToVector3(), start.ToVector3());
                    if (dis <= trainLen)
                    {
                        // 列车还未驶离奇观
                        aniPro = dis / trainLen;
                    }
                }
            }

            return aniPro;
        }

        // 初始化列车动画状态 
        // 列车从奇观里面驶出
        // 列车在奇观间正常行驶
        // 列车驶入奇观 -初始化的时候 玩家只能看到列车停在奇观内部 
        private void InitTrainAniState()
        {
            if (MarchInfo != null)
            {
                if (MarchInfo.ClientMarchStatue == EMarchStatus.WALK)
                {
                    // 驶出 or 正常行驶
                    UpdateTrainOutWonder();
                }
                else if (MarchInfo.ClientMarchStatue == EMarchStatus.Park)
                {
                    // 驶入某个奇观
                    TradeTrainModel train = squareModel as TradeTrainModel;
                    train?.OnMoveInWonder(1);
                }
            }
        }

        public void PlayDeathFrame()
        {
            SetSquareStatus(Enum_MarchState_PlyDIEIdle);
            SquareDataManager.Instance.PlayDeadAnim(squareDataIndex);
        }

        #endregion

        private bool isBattleTransforming = false;
        private float battleStartTime = -1;

        public void ReadyToBattle()
        {
            //Debug.Log(LogModule.RTS,$"  ReadyToBattle  {MarchInfo.Uid}  frameCount:{Time.frameCount}  targetId:{MarchInfo.TargetId}  currentForward:{MarchEntity.Forward} forward:{forward}");
            var forward = MarchInfo.GetTargetPosition() - MarchInfo.Position;
            MarchEntity.SetForward(forward);
            SetSquareStatus(Enum_MarchState_Attack);

            if (MarchEntity.Hud != null)
            {
                if (MarchEntity.Hud.HudType == HudType.Troop)
                {
                    var hud = MarchEntity.Hud as MarchHud;
                    hud?.SetIsInBattle(true);
                }
            }
        }

        public void ClientSetMarchAndTargetInBattle()
        {
            //防止对方移动 再次计算一次
            var target = MarchEntity.GetTarget();
            if (target != null && target.MarchInfo.SoldierCount > 0 && !target.IsMoving())
            {
                var forward = MarchInfo.GetTargetPosition() - MarchInfo.Position;
                if (target.Team == MarchHelper.TeamSelf)
                {
                    if (target.Hud != null)
                    {
                        if (target.Hud.HudType == HudType.Troop)
                        {
                            var hud = target.Hud as MarchHud;
                            hud?.SetIsInBattle(true);
                        }
                    }
                }
                if ((MarchEntity.Team == MarchHelper.TeamSelf || MarchEntity.Team ==  MarchHelper.TeamFriend) && target.Team == MarchHelper.TeamOther)
                {
                    target.SetTeam(MarchHelper.TeamEnemy);
                }

                if (target.GetBattleTarget() == null)
                {
                    target.SetBattleTargetId(MarchInfo.Uid, MarchEntity.RtsServerInfo.Type);
                    target.SetForward(-forward.normalized);
                }
                MarchEntity.SetBattleTargetId(target.MarchInfo.Uid, target.RtsServerInfo.Type);
                SetClientInBattle(true, false);
                MarchEntity.SetForward(forward.normalized);
                MarchEntity.SetMarchStatus(EMarchStatus.Battle);
                SetSquareStatus(Enum_MarchState_Attack);
                MarchInfo.SetIsClientInBattle(true);
                if (MarchEntity.Hud != null)
                {
                    if (MarchEntity.Hud.HudType == HudType.Troop)
                    {
                        var hud = MarchEntity.Hud as MarchHud;
                        hud?.SetIsInBattle(true);
                    }
                }
                var targetSquare = target.GetBattleSquare();
                if (targetSquare != null)
                {
                    target.SetMarchStatus(EMarchStatus.Battle);
                    targetSquare.SetClientInBattle(true, false);
                    targetSquare.SetSquareStatus(Enum_MarchState_Attack);

                }
            }
            MarchEntity.RtsServerInfo.pathList = null;
            MarchInfo.ClientAttackPosition = Vector3.zero;
        }

        internal void ClientStartFight()
        {
            var target = MarchEntity.GetTarget();
            if (target != null && target.MarchInfo.SoldierCount > 0 && !target.IsMoving())
            {
                var forward = MarchInfo.GetTargetPosition() - MarchInfo.Position;
                if (target.GetBattleTarget() == null)
                {
                    target.SetBattleTargetId(MarchInfo.Uid, MarchEntity.RtsServerInfo.Type);
                    target.SetForward(-forward.normalized);
                    target.SetMarchStatus(EMarchStatus.Battle);
                    if (target.Team == MarchHelper.TeamOther)
                    {
                        target.SetTeam(MarchHelper.TeamEnemy);
                    }
                    var targetSquare = target.GetBattleSquare();
                    if (targetSquare!=null)
                    {
                        targetSquare.SetClientInBattle(true, false);
                        targetSquare.SetSquareStatus(Enum_MarchState_Attack);
                    }
                }

                if (target.Hud != null)
                {
                    if (target.Hud.HudType == HudType.Troop)
                    {
                        var hud = target.Hud as MarchHud;
                        hud?.SetIsInBattle(true);
                    }
                }
            }
        }


        private void RemoveSelfTroopEffect()
        {
            if (_troopSelfTroopEffect != null)
            {
                ArmyManager.Instance.GetRtsResourceManager().RecoverResourceById(705,_troopSelfTroopEffect);
                _troopSelfTroopEffect = null;
            }
        }
        public void InitChildren()
        {
            //通过数据模式创建小兵
            InitMarchSquareData();
            SetArmyVisible(visible);
        }

        private bool isShowAmbulance = false;
        private bool isEscape = false;
        private int ambulanceIndex = -1;

        public void TestEscape()
        {
            StartEscape();
            //ShowAmbulance();
        }

        //public void ShowAmbulance()
        //{
        //    if (!isShowAmbulance)
        //    {
        //        ambulanceIndex = SquareDataManager.Instance.ShowAmbulance(squareDataIndex,Forward);
        //        isShowAmbulance = true;
        //    }
        //}

        private void StartEscape(bool isAllDead = false)
        {
            SquareDataManager.Instance.SetEscapeNew(squareDataIndex,isAllDead);
        }

        public void SetEscapeWithoutAmbulance()
        {
            if (MarchEntity.TargetCoordinateType == TargetCoordinateType.ASSEMBLY_20)
            {
                SquareDataManager.Instance.SetSpeed(squareDataIndex,2000 / 3600f);
            }
            SquareDataManager.Instance.SetEscapeWithoutAmbulance(squareDataIndex, 0);
        }

        private void StartEscapeWithoutAmbulance(int survivalCount)
        {
            bool bShowEscape = MarchEntity != null && !MarchEntity.isMonster;
            if (MarchInfo.SoldierCount == 0)
            {
                if (bShowEscape)
                {
                    MarchManager.Instance.CreateEsCapeEffect(MarchEntity.Position);
                    if (MarchEntity!=null && _marchSkinResId != 0)
                    {
                        RemoveTroopMarchSkin(_marchSkinResId);
                    }
                }
            }
            if (bShowEscape)
            {
                SquareDataManager.Instance.SetEscapeWithoutAmbulance(squareDataIndex, survivalCount);
            }
            SetFormationType(formationType,0);
        }

        public void InitModel()
        {
            if (!initedModel)
            {
                initedModel = true;
                var path = ArmyManager.Instance.ResourceManager.GetModelPathByName(MarchEntity.RtsServerInfo.modelName);
                ArmyManager.Instance.ResourceManager.LoadModel(path, (gameObj) =>
                {
                    if (squareModel == null)
                    {
                        SquareModel model = null;
                        if (MarchEntity.TargetCoordinateType == TargetCoordinateType.DONALD_BOSS_38)
                        {
                            model = new HeroBossModel();   
                        }
                        else if (MarchEntity.TargetCoordinateType == TargetCoordinateType.TRAIN_51)
                        {
                            model = new TradeTrainModel();
                  
                        }
                        else
                        {
                            model = new SquareModel();
                        }
                        model.GameObject = gameObj;
                        model.Transform = gameObj.transform;
                        gameObj.transform.SetParent(MarchEntity.GetGameObject().transform,false);
                        gameObj.transform.localPosition = Vector3.zero;
                        gameObj.transform.forward = MarchEntity.MarchInfo.CurrentForward;
                        squareModel = model;
                        squareModel.Init(MarchEntity.AudioEmitter);
                        if (MarchEntity.RtsServerInfo.isNewFromServer)
                        {
                            MarchEntity.RtsServerInfo.isNewFromServer = false;
                            squareModel.PlayAnimation("Born");
                        }
                        if (MarchEntity.RtsServerInfo.Type == TargetCoordinateType.ALLIANCE_PRACTICE_BOSS_32 || MarchEntity.RtsServerInfo.Type == TargetCoordinateType.DONALD_BOSS_38
                            || MarchEntity.RtsServerInfo.Type == TargetCoordinateType.WORLD_BOSS_44)
                        {
                            if (MarchEntity.RtsServerInfo.Type == TargetCoordinateType.ALLIANCE_PRACTICE_BOSS_32
                                || MarchEntity.RtsServerInfo.Type == TargetCoordinateType.WORLD_BOSS_44)
                            {
                                model?.setDefaultAperture(model.Transform.Find("sfx_rts_worldboss_halo001").gameObject);
                            }
                            var viewCheck = gameObj.AddComponent<UnionTrialBossViewCheck>();
                            viewCheck.unionId = MarchEntity.RtsServerInfo.alliandeId;
                            viewCheck.uid = MarchEntity.RtsServerInfo.tid;
                            viewCheck.type = (int)MarchEntity.RtsServerInfo.Type;
                            viewCheck.maxHp = MarchEntity.RtsServerInfo.initSoldierCount;
                            viewCheck.currentHp = MarchEntity.RtsServerInfo.soldierCount;
                            bossView = viewCheck;
                        }

                        if (MarchEntity.RtsServerInfo.Type == TargetCoordinateType.TRAIN_51)
                        {
                            InitTrainAniState();
                            TradeTrainModel train = squareModel as TradeTrainModel;
                            CapsuleCollider collider = train.GetCollider();
                            if (collider)
                            {
                                MarchEntity.Mono.SetColliderTrain(collider);
                            }
                        }

                        SetPosition(MarchEntity.Position, MarchEntity.MarchInfo.IsForceMoveChild);
                        SetForward(MarchEntity.Forward);
                    }
                    else
                    {
                        GameObject.Destroy(gameObj);
                    }
                });
            }
        }

        public void UpdateModelSoldierNum()
        {
            bossView?.UpdateMaxHp(MarchEntity.RtsServerInfo.initSoldierCount);
        }
        
        public void CheckNeedResetChildrenNum(int squareSoldierCount,bool forceSet = false)
        {
            if (squareSoldierCount == 0)
            {
                if (!isEscape)
                {
                    if (MarchEntity.ClientMarchType == EClientMarchType.March && MarchInfo.ClientMarchStatue == EMarchStatus.Escape)
                    {
                        isEscape = true;
                        //StartEscape(false);
                        StartEscapeWithoutAmbulance(GetEscapeSoldierCount());
                        //SquareDataManager.Instance.SetEscape(squareDataIndex,GetEscapeSoldierLodIdList());
                    }
                    else if (MarchEntity.ClientMarchType == EClientMarchType.Monster)
                    {
                        StartEscapeWithoutAmbulance(0);
                    }
                    HideAttackSpeedEffect();
                }
                return;
            }
            else if (SoldierLodIdList.Count == 0 && MarchInfo.NeedShowSquare() && visible)
            {
                ResetFormation();
            }
            return;
            //UpdateSoldierNum(squareSoldierCount,forceSet)
        }

        public void UpdateSoldierNum(int squareSoldierCount,bool isForceDead)
        {
            //先根据当前剩余兵力，决定阵型
            var newSoldierLodIdList = GetSoldierLodIdList(squareSoldierCount);
            if (newSoldierLodIdList != null)
            {
                var changeDic = new Dictionary<int, int>();

                for (int i = 0; i < newSoldierLodIdList.Count; i++)
                {
                    var soldierId = newSoldierLodIdList[i];
                    if (changeDic.TryGetValue(soldierId, out var count))
                    {
                        changeDic[soldierId] = count + 1;
                    }
                    else
                    {
                        changeDic[soldierId] = 1;
                    }
                }

                for (int i = 0; i < SoldierLodIdList.Count; i++)
                {
                    var soldierId = SoldierLodIdList[i];
                    if (changeDic.TryGetValue(soldierId, out var count))
                    {
                        changeDic[soldierId] = count - 1;
                    }
                    else
                    {
                        changeDic[soldierId] = -1;
                    }
                }
                SoldierLodIdList.Clear();
                SoldierLodIdList.AddRange(newSoldierLodIdList);
                SquareDataManager.Instance.UpdateChildDeadOrReborn(squareDataIndex, changeDic, isForceDead);
            }
        }

        
        public void UpdateSoldierInfo(int soldierCount)
        {
            //var showBattleSquare = MarchManager.marchContext.showMarchSquare;
            int formationType = -1;

            if (MarchEntity.ClientMarchType == EClientMarchType.Scout || MarchEntity.ClientMarchType == EClientMarchType.Rescue) // 侦察队列
            {
                formationType = 9999;
            }
            else if(MarchEntity.RtsServerInfo.Type == TargetCoordinateType.ASSEMBLY_20)
            {
                formationType = 1001;//集结部队
            }
            else if (MarchEntity.RtsServerInfo.Type == TargetCoordinateType.DONALD_BOSS_38 || MarchEntity.RtsServerInfo.Type == TargetCoordinateType.SMUGGLER_30)
            {
                formationType = MarchEntity.RtsServerInfo.formationId;
            }
            else if (MarchEntity.RtsServerInfo.Type == TargetCoordinateType.CARGO_TRUCK_42)
            {
                LuaFunction call = LuaManager.mainState.GetFunction("G_ActivityHelper.getCarGoFormationType");
                object[] luaTable = call.Call();
                foreach (var obj in luaTable)
                {
                    int.TryParse(obj.ToString(),out formationType);
                    break;
                }
            }
            else if (isTruck)
            {
                formationType = MarchHelper.TradeTruckFormationId;
            }
            else if (isTruckAttack || isTrainAttack)
            {
                formationType = MarchHelper.TradeTruckAttackerFormationId;
            }
            else
            {
                var serverSoldierCount = MarchEntity.RtsServerInfo.soldierCount;
                if (serverSoldierCount >= 0) //攻击城市的时候、死亡队列，soldierList会为空
                {
                    //Dictionary<int, int> sttt = new Dictionary<int, int>(10);
                    //统计小兵数量&种类等
                    //由于只需要判断到底是不是多兵种，因此不需要创建一个dictionary
                    int soldierType = MarchEntity.MarchInfo.SoldierType;
                    bool isMultiSoldierType = soldierType == 5;
                    // 计算阵型配置
                    if (isMultiSoldierType) // 多兵种
                    {
                        if (MarchEntity.ClientMarchType == EClientMarchType.Monster)
                        {
//                            formationType = 202;  //野怪多兵种
                            formationType = MarchEntity.RtsServerInfo.formationId;
                        }else //其他就用普通兵种
                        {
                            formationType = 1001;  //普通
                        }
                    }
                    else
                    {
                        if (MarchEntity.ClientMarchType == EClientMarchType.Monster)
                        {
                            formationType = MarchEntity.RtsServerInfo.formationId;
                        }
                        else
                        {
                            formationType = soldierType;
                        }
                    }
                }
                else
                {
                }
            }

            if (formationType != -1)
            {
                if (BattleFormationHelper.getFormation(formationType, ref formationCfgs))
                {
                    this.formationType = formationType;

                    // 如果有阵型，(formationType==0：建筑物)
                    if (formationCfgs != null)
                    {
                        if (!initedChildren)
                        {
                            modelTotalNum = 0;
                            //Profiler.BeginSample("[C#]MarchManager.UpdateMarchInfo.Square.GetSoldierLodIdList");
                            SoldierLodIdList.Clear();
                            if (MarchInfo.SoldierCount == 0 && MarchEntity.ClientMarchType != EClientMarchType.Scout &&
                                MarchEntity.ClientMarchType != EClientMarchType.Rescue)
                            {
                                SoldierLodIdList.AddRange(GetSoldierLodIdList(MarchEntity.RtsServerInfo.soldierCount));
                            }
                            else if (MarchEntity.ClientMarchType == EClientMarchType.Scout)
                            {
                                SoldierLodIdList.AddRange(GetScoutSoldierLodIdList());
                            }
                            else if (MarchEntity.ClientMarchType == EClientMarchType.Rescue)
                            {
                                SoldierLodIdList.AddRange(GetScoutSoldierLodIdList());
                            }
                            else
                            {
                                SoldierLodIdList.AddRange(GetSoldierLodIdList(MarchEntity.RtsServerInfo.initSoldierCount));
                            }

                            //Profiler.EndSample();
                            if (SoldierLodIdList == null || SoldierLodIdList.Count == 0)
                            {
                                //UnityEngine.Debug.LogError(MarchEntity.Tid+"士兵阵型获取失败");
                            }

                            //Profiler.BeginSample("[C#]MarchManager.UpdateMarchInfo.Square.InitChildren");
                            InitChildren();
                            SquareDataManager.Instance.SetFomationIndexOffset(squareDataIndex,
                                GetformationPositionIndex());
                            //Profiler.EndSample();
                            //Profiler.BeginSample("[C#]MarchManager.UpdateMarchInfo.Square.InitMarch");
                            InitMarch();
                            //Profiler.EndSample();
                            //Profiler.BeginSample("[C#]MarchManager.UpdateMarchInfo.Square.SetMarchDataToSquareData");
                            SetMarchDataToSquareData();
                            //Profiler.EndSample();
                            initedChildren = true;
                        }

                        SetFormationType(formationType, soldierCount);
                        // Debug.Log($" tid = {Tid} UpdateBattleDetailInfo  posLen = {this.formationPos.Count} SoldierLodIdList = {SoldierLodIdList.Count}");
                    }
                }
            }
        }

     

        /// <summary>
        /// 根据方阵士兵数量 刷新当前士兵模型数量
        /// </summary>
        /// <param name="squareSoldierCount"></param>
        private void RefreshCurrentSoldierCountDic(int soldierNum,List<int> soldierPair)
        {
            int totalModelCountx = MarchEntity.UpateModelTotalNumBySoldierCount(soldierNum);
            
            foreach (var ik in _soldierIdCountCurrentDic.Keys.ToArray())
            {
                if (totalModelCountx > _soldierIdCountCurrentDic[ik])
                {
                    totalModelCountx -= _soldierIdCountCurrentDic[ik];
                }
                else
                {
                    _soldierIdCountCurrentDic[ik] = totalModelCountx;
                    totalModelCountx = 0;
                }
            }

            return;
            //如果为空就用MarchEntity统计的数据;soldierPair 是由roundfight传进来的
            if (soldierPair == null)
            {
                _soldierIdCountCurrentDic.Clear();
                var lod0IdList = SoldierLodIdList;
                for (int i = 0; i < lod0IdList.Count; i++)
                {
                    int soldierId = lod0IdList[i];
                    if (!_soldierIdCountCurrentDic.ContainsKey(soldierId))
                    {
                        _soldierIdCountCurrentDic.Add(soldierId, 0);
                    }
                    _soldierIdCountCurrentDic[soldierId]++;
                }
            }
            else
            {
                //TODO: 固定小兵的这里怎么处理？
                _soldierIdCountCurrentDic.Clear();
                int totalModelCount = MarchEntity.UpateModelTotalNumBySoldierCount(soldierNum);
                totalModelCount = totalModelCount == 0 ? 1 : totalModelCount; //如果一个都没，就给一个
                int leftNum = totalModelCount;
                for (int i = 0; i < soldierPair.Count; i++)
                {
                    int sp = soldierPair[i];
                    int soldierId = sp >> 16;
                    int soldierCount = (sp & 65535) * 1000;
                    int sc = Mathf.FloorToInt(soldierCount / soldierNum * totalModelCount);
                    sc = sc == 0 ? 1 : sc;    // 一个兵种如果不满1/modelTotalNum，依然给一个位置
                    if (sc <= leftNum && leftNum > 0) 
                    {
                        if (!_soldierIdCountCurrentDic.ContainsKey(soldierId))
                        {
                            _soldierIdCountCurrentDic.Add(soldierId, 0);
                        }
                        _soldierIdCountCurrentDic[soldierId] = sc;
                        leftNum -= sc;
                    }
                }
            }
        }
        
        private List<int> tempSoldierLodIdList = new List<int>(10);
        private List<int> SoldierLodIdList = new List<int>(10);
        
        public int GetformationPositionIndex()
        {
            if(formationCfgs!= null)
            {
                for (int i = formationCfgs.Count - 1; i > -1; i--)
                {
                    var cfg = formationCfgs[i];
                    return cfg.formationPositionIndex;
                }
            }
            return 1;
        }
        public int GetEscapeSoldierCount()
        {
            if (MarchEntity.isExpeditionMarch)
            {
                return 0;
            }
            if(formationCfgs!= null)
            {
                for (int i = formationCfgs.Count - 1; i > -1; i--)
                {
                    var cfg = formationCfgs[i];

                    if ((int)FormationType.Dead == cfg.soldierNum)
                    {
                        return cfg.modelNum;
                    }
                }
            }
            return 0;
        }
        
        public List<int> GetScoutSoldierLodIdList()
        {
            if (formationCfgs != null)
            {
                for (int i = formationCfgs.Count - 1; i > -1; i--)
                {
                    var cfg = formationCfgs[i];

                    if (RTSQualityHelper.IsSimpleMode)
                    {
                        if (cfg.soldierNum == (int)FormationType.Simple)
                        {
                            modelTotalNum = cfg.soldierLocation.Count;
                            this.formationPos = cfg.soldierLocation;
                            break;
                        }
                    }
                    else
                    {
                        if ((int)FormationType.Normal == cfg.soldierNum)
                        {
                            modelTotalNum = cfg.soldierLocation.Count;
                            this.formationPos = cfg.soldierLocation;
                            break;
                        }
                    }
                }
            }
            tempSoldierLodIdList.Clear();
            var ScoutSoldierId = BattleUtils.ScoutSoldierId;
            foreach (var soldierLocation in this.formationPos)
            {
                tempSoldierLodIdList.Add(ScoutSoldierId);
            }
            return tempSoldierLodIdList;
        }

       /* public List<int> GetScureSoldierLodIdList()
        {
            if (formationCfgs != null)
            {
                for (int i = formationCfgs.Count - 1; i > -1; i--)
                {
                    var cfg = formationCfgs[i];

                    if (RTSQualityHelper.IsSimpleMode)
                    {
                        if (cfg.soldierNum == (int)FormationType.Simple)
                        {
                            modelTotalNum = cfg.soldierLocation.Count;
                            this.formationPos = cfg.soldierLocation;
                            break;
                        }
                    }
                    else
                    {
                        if ((int)FormationType.Normal == cfg.soldierNum)
                        {
                            modelTotalNum = cfg.soldierLocation.Count;
                            this.formationPos = cfg.soldierLocation;
                            break;
                        }
                    }
                }
            }
            tempSoldierLodIdList.Clear();
            var ScoutSoldierId = BattleUtils.ScureSoldierId;
            foreach (var soldierLocation in this.formationPos)
            {
                tempSoldierLodIdList.Add(ScoutSoldierId);
            }
            return tempSoldierLodIdList;
        }
        */
        public List<int> GetSoldierLodIdList(int squareSoldierCount)
        {
            fixedSoldierID = false;
            int currentModelTotalNum = modelTotalNum;
            modelTotalNum = 0;
            if(formationCfgs!= null)
            {
	            for (int i = formationCfgs.Count - 1; i > -1; i--)
	            {
	                var cfg = formationCfgs[i];

                    if (RTSQualityHelper.IsSimpleMode)
                    {
                        if (cfg.soldierNum == -1)
                        {
                            modelTotalNum = cfg.modelNum;
                            this.formationPos = cfg.soldierLocation;
                            fixedSoldierID = cfg.fixedSoldierID == 1;
                            if (currentModelTotalNum == modelTotalNum)
                            {
                                return null;
                            }
                            break;
                        }
                    }
                    else
                    {
                        if (squareSoldierCount >= cfg.soldierNum)
                        {
                            modelTotalNum = cfg.modelNum;
                            this.formationPos = cfg.soldierLocation;
                            fixedSoldierID = cfg.fixedSoldierID == 1;
                            if (currentModelTotalNum == modelTotalNum)
                            {
                                return null;
                            }
                            break;
                        }
                    }
 	            }
 	        }
            tempSoldierLodIdList.Clear();
            //是否按照配表里配置的兵种id显示
            if (fixedSoldierID)
            {
                foreach (var soldierLocation in this.formationPos)
                {
                    if (soldierLocation.id > 0)
                    {
                        tempSoldierLodIdList.Add(soldierLocation.id);
                    }
                }
            }
            else
            {
                // 如果阵型没有指定兵，就按照比例显示真正的兵种
                int leftNum = modelTotalNum;
                var access = MarchEntity.MarchInfo.soldierListAccess;
                if (access!=null && access.IsValid())
                {
                    for (int i = 0; i < MarchEntity.MarchInfo.SoldierListLength; i++)
                    {
                        if (leftNum > 0)
                        {
                            int initNum = access.GetInt(i * 5 + 2); 
                            int soldierId = access.GetInt(i * 5 + 1);
                            int mm = squareSoldierCount == 0 ? 0 : Mathf.CeilToInt(initNum / (float)MarchInfo.InitSoldierCount * modelTotalNum);
                            mm = mm <= 0 ? 1 : mm;    // 一个兵种如果不满1/modelTotalNum，依然给一个位置
                            for (int j = 0; j < mm; j++)
                            {
                                if (leftNum > 0)
                                {
                                    leftNum--;
                                    tempSoldierLodIdList.Add(soldierId);
                                }
                                else
                                {
                                    return tempSoldierLodIdList;
                                }
                            }
                        }
                    }
                }
            }
            return tempSoldierLodIdList;
        }
        
        
        private void InitMarch()
        {
            SetChildrenPosition(true);
            SetForward(MarchEntity.Forward, true);
        }


#if UNITY_EDITOR
        public void ReloadChildParticleConfig()
        {
            /*foreach (var soldier in _soldiersList)
            {
                soldier.ReloadThrowableData();
            }

            foreach (var commander in _commanderList)
            {
                commander.ReloadThrowableData();
            }*/

            int attackDataIndex = 2000 + MarchInfo.SoldierType;//不同兵种用不同的攻击特效 混兵使用2005
            attackData = ArmyManager.Instance.ResourceManager.JsonManager.GetThrowableConfigBySoldierType(attackDataIndex);
        }

        public void ReloadChildActionConfig()
        {
            /*foreach (var soldier in _soldiersList)
            {
                soldier.ReloadActionConfig();
            }

            foreach (var commander in _commanderList)
            {
                commander.ReloadActionConfig();
            }*/
        }

        public void EditorResetScale()
        {
           
        }

        public void ResetSoldierShadowPosition()
        {
            
        }
#endif

        /// <summary>
        /// 由于性能预算不足，隐藏部分模型
        /// </summary>
        /// <param name="count"></param>
        /// <returns></returns>
        public int Discard(int count)
        {
            return 0;
            /*if (_soldiersList == null)
                return 0;

            int discard = 0;
            for (var i = _soldiersList.Count - 1; i >= 0; i--)
            {
                var soldierUnit = _soldiersList[i];
                if (soldierUnit.GetRenderVisible())
                {
                    soldierUnit.IsDiscard = true;
                    discard++;
                    if (discard >= count)
                        break;
                }
            }

            return discard;*/
        }

        /// <summary>
        /// 由于性能预算有空闲，恢复部分模型
        /// </summary>
        /// <param name="count"></param>
        /// <returns></returns>
        public int Recover(int count)
        {
            return 0;
            /*if (_soldiersList == null)
                return 0;

            int recover = 0;
            for (var i = 0; i < _soldiersList.Count; i++)
            {
                var soldierUnit = _soldiersList[i];
                if (soldierUnit.IsDiscard)
                {
                    soldierUnit.IsDiscard = false;

                    if (soldierUnit.GetRenderVisible())
                    {
                        recover++;
                        if (recover >= count)
                            break;
                    }
                }
            }

            return recover;*/
        }

        private List<float> _attackTime = new List<float>()
        {
            0.08f,0.15f,0.21f,0.28f,0.36f,0.47f,0.59f,0.67f
        };
        private float[] _attackTimeArray = new float[5];
        private int _currentIndex;
        private float realTime;
        public Vector3 _currentShowForward;


        private void InitAttackEffectIntervalParam()
        {
            for (int i = 0; i < _attackTimeArray.Length; i++)
            {
                _attackTimeArray[i] = 0.1f * i + Random.Range(-0.05f, 0.05f);
            }
            attackCurrentTime2 = 0;
            //RTSMono.Instance.StartCoroutine(PlayAttackEffectCoroutine(6));
        }

        internal void PlaySkillAnimation(string animation)
        {
            squareModel?.PlayAnimation(animation);
        }

        internal void SetAttackAnimationSpeed(float animationSpeed, float speedTime)
        {
            squareModel.SetAttackAnimationSpeed(animationSpeed, speedTime);
        }

        // private void UpdateAttackEffect()
        // {
        //     attackCurrentTime2 += Time.deltaTime;
        //     for (int i = 0; i < _attackTimeArray.Length; i++)
        //     {
        //         if (attackCurrentTime2 > _attackTimeArray[i] && _attackTimeArray[i] != 0)
        //         {
        //             var angle = PveUtils.GetAngle(Vector3.forward, Forward);
        //             int randomIndex = Random.Range(0, BattleFormationHelper.AttackEffectPosList.Count);
        //             var attackEffectPos = BattleFormationHelper.AttackEffectPosList[randomIndex];
        //             var startPos = Quaternion.AngleAxis(angle, Vector3.up) * attackEffectPos + MarchInfo.Position;
        //             var targetPos = MarchInfo.GetTargetPosition() + Quaternion.AngleAxis(angle, Vector3.up) * attackEffectPos;
        //             ThrowableManager.StartShootTrack(null, null, targetPos, attackData, startPos, MarchInfo.SoldierType == (int)SoldierType.Gerenerde);
        //             _attackTimeArray[i] = 0;
        //         }
        //     }
        // }

        // private IEnumerator PlayAttackEffectCoroutine(int times)
        // {
        //     for (int i = 0; i < times; i++)
        //     {
        //         int index = Random.Range(0, _attackTime.Count);
        //         yield return new WaitForSeconds(0.1f + Random.Range(-0.05f,0.05f));
        //         if (MarchClientMarchStatue == EMarchStatus.Battle)
        //         {
        //             var angle = PveUtils.GetAngle(Vector3.forward, Forward);
        //             var attackEffectPos = BattleFormationHelper.AttackEffectPosList[index];
        //             var startPos = Quaternion.AngleAxis(angle, Vector3.up) * attackEffectPos + MarchInfo.Position;
        //             var targetPos = MarchInfo.GetTargetPosition() + Quaternion.AngleAxis(angle, Vector3.up) * attackEffectPos;
        //             ThrowableManager.StartShootTrack(null, null, targetPos, ArmyManager.Instance.ResourceManager.JsonManager.GetThrowableConfigBySoldierType(3), startPos);
        //         }
        //     }
        // }

        public void SetClientInBattle(bool isInBattle,bool isCityBattle, bool isRelatedToSelf = false)
        {
            if (isInBattle)// && !isCityBattle)
            {
                if (!isClientInBattle && !isBattleTransforming && MarchEntity.MarchInfo.ClientMarchStatue != EMarchStatus.Collect)
                {
                    isBattleTransforming = true;
                    battleStartTime = TimeUtils.GetClientTickTime();
                }

                if (isBattleTransforming)
                {
                    HideAttackSpeedEffect();
                }
                else
                {
                    ShowAttackSpeedEffect(isRelatedToSelf);
                }
            }
            else
            {
                HideAttackSpeedEffect();
            }

            if (isInBattle != isClientInBattle)
            {
                SquareDataManager.Instance.SetClientInBattle(squareDataIndex,isInBattle);
                isClientInBattle = isInBattle;
            }
        }
        
        private bool isClientInBattle = false;
        
        private int attackSpeedEffectId;
        private GameObject attackSpeedEffect;
        private Transform attackSpeedEffectOriginParent;
        private bool attackSpeedEffectRelatedToSelf = false;
        
        /// <summary>
        /// 显示攻击速度线
        /// </summary>
        /// <param name="isRelatedToSelf"></param>
        public void ShowAttackSpeedEffect(bool isRelatedToSelf = false)
        {
            if (attackSpeedEffectId == 0)
            {
                attackSpeedEffectId = Team == 0 ? 1011 : 1012;
            }
            if (attackSpeedEffect == null)
            {
                attackSpeedEffectRelatedToSelf = isRelatedToSelf;
                var isPlayEffect = isRelatedToSelf;
                if (!isRelatedToSelf)
                {
                    isPlayEffect = RTSQualityHelper.IsShowThirdAttackSpeedLineEffect;
                }
                if (isPlayEffect && RTSQualityHelper.ShowAttackSpeed())
                {
                    attackSpeedEffect = ArmyManager.GetEffectById(attackSpeedEffectId, isRelatedToSelf);
                    if (attackSpeedEffect != null)
                    {
                        //attackSpeedEffectOriginParent = attackSpeedEffect.transform.parent;
                        //attackSpeedEffect.transform.SetParent(GetGameObject().transform);
                        //attackSpeedEffect.transform.localScale = Vector3.one;
                        //attackSpeedEffect.transform.localEulerAngles = Vector3.zero;
                        //attackSpeedEffect.transform.localPosition = Vector3.zero;
                        attackSpeedEffect.transform.localScale = new Vector3(1, 1, 1f);
                    }
                }
            }
            if (attackSpeedEffect)
            {
                attackSpeedEffect.SetActive(true);
            }
       
        }

        private void HideAttackSpeedEffect()
        {
            if (attackSpeedEffect != null)
            {
                //attackSpeedEffect.transform.SetParent(attackSpeedEffectOriginParent);
                ArmyManager.RecoverEffectById(attackSpeedEffectId,attackSpeedEffect,attackSpeedEffectRelatedToSelf);
                attackSpeedEffect = null;
            }
        }

        public void SetBesiege(bool isBesiege)
        {
            SquareDataManager.Instance.SetBesiege(squareDataIndex,isBesiege);
        }

        public void FakeKnockBack(Vector3 forward, int count,int externalSoldierId = -1)
        {
            if (_beforeLodLevel >= 3)
            {
                return;
            }
            //唐纳德不抛飞
            if (MarchEntity.TargetCoordinateType == TargetCoordinateType.DONALD_BOSS_38)
            {
                return;
            }
            SquareDataManager.Instance.ShowFakeKnockBack(squareDataIndex,forward,count,externalSoldierId);
        }

        private bool isFakeMoveForward = false;
        private bool isFakeMoveForwardEnd = false;
        private float fakeMoveForwardTime = -1;
        private float fakeMoveForwardEndTime = -1;
        private Vector3 fakeMoveForwardTargetPosition;

        public void FakeMoveForward(Vector3 startPosition, Vector3 targetPosition,float speed = -1)
        {
            if (isFakeMoveForward)
            {
                return;
            }
            
            Yoozoo.Gta.Common.ResidentHandler.Inst.GetFunction("G_MarchManager.StopFakeMoveForward")
                .Func<long, Vector3, bool>(MarchEntity.Tid, startPosition);
            
            isFakeMoveForward = true;
            fakeMoveForwardTime = TimeUtils.GetClientTickTime();
            var marchRealSpeed = MarchInfo.Speed;
            if (speed > 0)
            {
                SquareDataManager.Instance.SetSpeed(squareDataIndex,speed);
                marchRealSpeed = speed;
            }
            SquareDataManager.Instance.ShowFakeMoveForward(squareDataIndex, startPosition, targetPosition);
            fakeMoveForwardEndTime = Vector3.Distance(startPosition, targetPosition) / marchRealSpeed + fakeMoveForwardTime;
            fakeMoveForwardTargetPosition = targetPosition;
            //UnityEngine.Debug.LogError(MarchEntity.Tid + " " + fakeMoveForwardEndTime + " " + fakeMoveForwardTargetPosition);
        }

        private void StopFakeMoveForward()
        {
            //UnityEngine.Debug.LogError(MarchEntity.Tid + " StopFake");
            SquareDataManager.Instance.StopFakeMoveForward(squareDataIndex, fakeMoveForwardTargetPosition);
            

        }
        
        public void EndFakeForward()
        {
            if (isFakeMoveForward)
            {
                StopFakeMoveForward();
            }
            isFakeMoveForward = false;
            isFakeMoveForwardEnd = false;
        }
        
        public void ResetFormation()
        {
            if (squareDataIndex < 0)
            {
                return;
            }
            modelTotalNum = 0;
            SoldierLodIdList.Clear();
            SoldierLodIdList.AddRange(GetSoldierLodIdList(MarchInfo.InitSoldierCount));
            SetFormationType(formationType, MarchInfo.SoldierCount);
            if (SoldierLodIdList == null)
            {
                UnityEngine.Debug.LogError(MarchEntity.Tid + "士兵阵型获取失败");
            }
            //InitChildren();
            SquareDataManager.Instance.InitSquare(squareDataIndex, MarchInfo.Uid,MarchEntity.TargetCoordinateType, SoldierLodIdList, MarchEntity.ClientMarchType == EClientMarchType.Monster, MarchInfo.SoldierCount == 0, MarchInfo.Team,this.formationPos);
            InitMarch();
            SetMarchDataToSquareData();
            if (!MarchEntity.Visible)
            {
                SquareDataManager.Instance.SetAlpha(squareDataIndex, 0);
            }
        }

        public void OnMarchStatusChanged()
        {
            if (_beforeLodLevel > 0)
            {
                CheckSelfTroopEffect(_beforeLodLevel);
            }

            if (isTruck)
            {
                UpdateTruckEffect();
            }
            else if (isTrain)
            {
                UpdateTrainEffect();
            }
        }

        public string GetDebugContent()
        {
            var content = "";
            content += string.Format("{0} = {1}\n", "squareDataIndex", squareDataIndex);
            content += string.Format("{0} = {1}\n", "cachedSquareStatus", cachedSquareStatus);
            content += string.Format("{0} = {1}\n", "isFakeMoveForward", isFakeMoveForward);
            content += string.Format("{0} = {1}\n", "_targetAlpha", _targetAlpha);
            content += string.Format("{0} = {1}\n", "SoldierCount ", MarchEntity.RtsServerInfo.soldierCount);
            content += string.Format("{0} = {1}\n", "cachedSoldierCount ", cachedSoldierCount);
            content += string.Format("{0} = {1}\n", "cachedFormationType ", cachedFormationType);
            content += string.Format("{0} = {1}\n", "visible", visible);
            content += string.Format("{0} = {1}\n", "alpha", alpha);
            content += string.Format("{0} = {1}\n", "initedModel", initedModel);
            content += string.Format("{0} = {1}\n", "isEscape", isEscape);
            content += string.Format("{0} = {1}\n", "startDispose", _startDispose);
            content += string.Format("{0} = {1}\n", "startHide", _startHide);
            return content;
        }
        
        public void OnsetDefaultApertureActive(bool active)
        {
            squareModel?.getDefaultAperture()?.SetActive(active); 
        }

        private GameObject smuggleEffect;
        public void UpdateSmuggleEffect()
        {
            if (MarchEntity.RtsServerInfo.marchStatus == MarchStatus.INIT_0 && MarchEntity.RtsServerInfo.expireMills > 0)
            {
                if (smuggleEffect==null)
                {
                    var effect = ArmyManager.Instance.GetRtsResourceManager().GetResourceById(1016);
                    effect.transform.SetParent(MarchEntity.Transform);
                    effect.transform.localPosition = new Vector3(0, 0, 0);
                    effect.transform.localScale = new Vector3(1f, 1f, 1f);
                    smuggleEffect = effect;
                }
            }
            else
            {
                DestroySmuggleEffect();
            }
        }

        private void DestroySmuggleEffect()
        {
            if (smuggleEffect!=null)
            {
                ArmyManager.Instance.GetRtsResourceManager().RecoverResourceById(1016,smuggleEffect);
                smuggleEffect = null;
            }
        }

        public void FadeIn(float time)
        {
            SetChildrenAlpha(0);
            _targetAlpha = 1;
            fadeTime = time;
            fadeStartTime = Time.time;
            fadeStartAlpha = 0;
        }

        public void FadeOut(float time,float delayTime = 0)
        {
            if (delayTime == 0)
            {
                SetChildrenAlpha(1);
                _targetAlpha = 0;
                fadeTime = time;
                fadeStartTime = Time.time;
                fadeStartAlpha = 1;
            }
            else
            {
                delayFadeTime = Time.time + delayTime;
                delayFadeTargetAlpha = 0;
                delayFadeDuration = time;
            }
        }

        private float truckCrushTime = -1;
        private float crushDuration = 1f;
        private float startCrushTime = -1f;
        private Vector3 crushDirection;

        public void SetTruckCrushTime(float crushTime, float crushDuration, Vector3 direction)
        {
            truckCrushTime = crushTime;
            this.crushDuration = crushDuration;
            this.crushDirection = direction;
        }

        private void UpdateTruckCrush()
        {
            if (truckCrushTime >= 0)
            {
                if (Time.time > truckCrushTime + crushDuration)
                {
                    truckCrushTime = -1;
                    startCrushTime = -1f;
                }
                else if (Time.time > truckCrushTime)
                {
                    SquareDataManager.Instance.SetMarchStatus(squareDataIndex,1);
                    var percent = (Time.time - startCrushTime) / crushDuration;
                    if (percent >= 1)
                    {
                        percent = 1;
                    }

                    var offsetPercent = 1 - Mathf.Abs(percent - 0.5f) / 0.5f;
                    SquareDataManager.Instance.SetPosition(squareDataIndex,MarchEntity.Position + crushDirection * 0.1f * offsetPercent,true);
                }
            }
        }

        public void StartTruckAttacking()
        {
            //SquareDataManager.Instance.SetMarchStatus(squareDataIndex,10,false);
            SquareDataManager.Instance.SetMarchStatus(squareDataIndex,Enum_MarchState_ExternalMovement);
        }

        public void UpdateTruckAttacking()
        {
            
        }

        private void UpdateTruckEffect()
        {
            var grabbedTimes = MarchEntity.RtsServerInfo.truckBeGrabbedTimes;
            if (grabbedTimes == 0)
            {
                return;
            }

            if (_beforeLodLevel >= 3)
            {
                HideTruckEffect();
                return;
            }
            if (truckEffect == null)
            {
                truckEffect = ArmyManager.GetResourceById(MarchHelper.TruckEffect);
                if (truckEffect)
                {
                    hasTruckEffect = true;
                    truckEffect.transform.SetParent(MarchEntity.GetGameObject().transform);
                    truckEffect.transform.localPosition = Vector3.zero;
                    truckEffectSub1 = truckEffect.transform.Find("1").gameObject;
                    truckEffectSub2 = truckEffect.transform.Find("2").gameObject;
                }
            }
            if (hasTruckEffect)
            {
                truckEffectSub1.SetActive(grabbedTimes > 0);
                truckEffectSub2.SetActive(grabbedTimes > 1);
                truckEffect.transform.forward = MarchEntity.Forward;
            }
        }

        private void HideTruckEffect()
        {
            if (hasTruckEffect)
            {
                ArmyManager.RecoverResourceById(MarchHelper.TruckEffect,truckEffect);
                truckEffect = null;
                truckEffectSub1 = null;
                truckEffectSub2 = null;
            }
            hasTruckEffect = false;
        }

        private int GetSquareTeam(int team)
        {
            //小兵阵营分为我方0,敌方2，中立3
            if (isTruck)
            {
                team = MarchHelper.GetTruckTeamColorByColor(MarchEntity.RtsServerInfo.truckColor);
            }
            else if (MarchEntity.isMonster && team == 2)
            {
                team = 3;
            }
            else if (team > 1)
            {
                team = 2;
            }
            return team;
        }

        #region 列车新增

        // 更新列车着火特效
        private void UpdateTrainEffect()
        {
            var grabbedTimes = MarchEntity.RtsServerInfo.trainBeGrabbedTimes;
            if (grabbedTimes == 0)
            {
                return;
            }

            if (_beforeLodLevel >= 3)
            {
                HideTrainEffect();
                return;
            }
            
            TradeTrainModel train = squareModel as TradeTrainModel;
            train?.UpdateFireShow(true,grabbedTimes,MarchEntity.Forward);
        }

        private void HideTrainEffect()
        {
            TradeTrainModel train = squareModel as TradeTrainModel;
            train?.Dispose();
        }

        #endregion
    }
}
